﻿using Basic.FlowApplication.Extend;
using Basic.FlowApplication.Interface;
using Basic.FlowApplication.Model;
using Basic.FlowApplication.Model.AuditLog;
using Basic.FlowRemoteModel;
using Basic.FlowRemoteModel.Application.Model;
using WeDonekRpc.Client.Attr;
using WeDonekRpc.Helper;

namespace Basic.FlowApplication.AuditEvent
{
    [IocName("Audit_2")]
    [ClassLifetimeAttr(ClassLifetimeType.SingleInstance)]
    internal class AuditBackEvent : IItemAuditEvent
    {

        public AfootAuditLogItem ItemAudit ( AuditFlowBody flow, FlowAuditLogState log, AuditRes result )
        {
            AfootAuditLogItem item = log.LogItem.Find(a => a.Id == result.ItemId);
            item.CheckAuditItem(result);
            FlowNode node = flow.Nodes[item.NodeId];
            if ( ( FlowAuditButton.退回 & node.AuditButton ) != FlowAuditButton.退回 )
            {
                throw new ErrorException("flow.audit.not.allow.back");
            }
            item.AuditState = FlowAuditItemStatus.已回退;
            item.AuditOpinion = result.Opinion;
            item.SignFileId = result.SignFileId;
            item.BackNodeId = result.BackNodeId;
            FlowNode backNode = flow.Nodes[result.BackNodeId.Value];
            List<AfootAuditLogItem> items = log.LogItem.FindAll(a => a.NodeId == backNode.Id && a.BatchNo == result.BackBatchNo.Value);
            if ( backNode.NodeType != FlowNodeType.循环处理节点 || backNode.Id != item.NodeId )
            {
                log.ToVoidItem(flow, backNode.Id, item.Id);
            }
            else if ( backNode.NodeType == FlowNodeType.循环处理节点 )
            {
                log.SetNodeState(backNode.Id, FlowNodeAuditStatus.审核进行中, item.Id);
            }
            DateTime now = DateTime.Now;
            items.ForEach(a =>
            {
                FlowNode cur = flow.Nodes[a.NodeId];
                log.LogItem.Add(new AfootAuditLogItem
                {
                    CompanyId = a.CompanyId,
                    EmpByDeptId = a.EmpByDeptId,
                    EmpByUnitId = a.EmpByUnitId,
                    EmpId = a.EmpId,
                    RootBatchNo = item.RootBatchNo,
                    RootNodeId = item.RootNodeId,
                    NextDeptId = a.NextDeptId,
                    NodeId = a.NodeId,
                    NodeType = cur.NodeType,
                    PrevBackNo = item.BatchNo,
                    PrevNodeId = item.NodeId,
                    PrtBatchNo = a.PrtBatchNo,
                    OptItemId = item.Id,
                    MarkState = FlowItemMarkState.退回,
                    TimeOut = cur.LimitTime.HasValue ? now.AddMinutes(cur.LimitTime.Value) : null
                });
            });

            return item;
        }
    }
}
